<template>
  <div class="home">
    <div class="toolbar">
      <button class="btn" @click="onZoomOut">-</button>
      <span class="scale">{{ scale.toFixed(2) }}</span>
      <button class="btn" @click="onZoomIn">+</button>
      <button class="btn" @click="onFitWidth">适配宽度</button>
      <button class="btn" @click="onFitPage">适配整页</button>
      <button class="btn" @click="onPrev">上一页</button>
      <button class="btn" @click="onNext">下一页</button>
      <span class="page">第 {{ currentPage }} 页</span>
      <input class="url" v-model="url" placeholder="输入 PDF 链接" />
      <button class="btn" @click="onLoad">加载</button>
    </div>
    <div ref="containerRef" class="pdf-container"></div>
  </div>
</template>

<script setup lang="ts">
import { onMounted, onBeforeUnmount, ref, markRaw } from 'vue'
import { PDFViewer } from '../../components/PDF/src'

const containerRef = ref<HTMLElement | null>(null)
const viewerRef = ref<PDFViewer | null>(null)
const scale = ref(1)
const currentPage = ref(1)
const url = ref(
  'https://mozilla.github.io/pdf.js/web/compressed.tracemonkey-pldi-09.pdf'
)

/**
 * @description 初始化 PDFViewer 并加载默认文档
 * @param 无
 * @returns void
 */
const initViewer = async (): Promise<void> => {
  if (!containerRef.value) return
  viewerRef.value = markRaw(
    new PDFViewer({ container: containerRef.value, initialScale: scale.value })
  )
  if (url.value) await viewerRef.value.load({ url: url.value })
  currentPage.value = viewerRef.value.getCurrentVisibleIndex()
  viewerRef.value.getBus().on('page:visible-change', (p: any) => {
    currentPage.value = p?.index ?? currentPage.value
  })
}

/**
 * @description 加载输入的 PDF 链接
 * @param 无
 * @returns void
 */
const onLoad = async (): Promise<void> => {
  if (!viewerRef.value || !url.value) return
  await viewerRef.value.load({ url: url.value })
}

/**
 * @description 放大视图
 * @param 无
 * @returns void
 */
const onZoomIn = (): void => {
  scale.value = Math.min(3, scale.value + 0.1)
  viewerRef.value?.setScale(scale.value)
  currentPage.value =
    viewerRef.value?.getCurrentVisibleIndex() ?? currentPage.value
}

/**
 * @description 缩小视图
 * @param 无
 * @returns void
 */
const onZoomOut = (): void => {
  scale.value = Math.max(0.5, scale.value - 0.1)
  viewerRef.value?.setScale(scale.value)
  currentPage.value =
    viewerRef.value?.getCurrentVisibleIndex() ?? currentPage.value
}

/**
 * @description 适配容器宽度
 * @param 无
 * @returns void
 */
const onFitWidth = (): void => {
  viewerRef.value?.fitWidth()
  currentPage.value =
    viewerRef.value?.getCurrentVisibleIndex() ?? currentPage.value
}

/**
 * @description 适配整页高度
 * @param 无
 * @returns void
 */
const onFitPage = (): void => {
  viewerRef.value?.fitPage()
  currentPage.value =
    viewerRef.value?.getCurrentVisibleIndex() ?? currentPage.value
}

/**
 * @description 上一页
 * @param 无
 * @returns void
 */
const onPrev = (): void => {
  viewerRef.value?.prevPage()
  currentPage.value =
    viewerRef.value?.getCurrentVisibleIndex() ?? currentPage.value
}

/**
 * @description 下一页
 * @param 无
 * @returns void
 */
const onNext = (): void => {
  viewerRef.value?.nextPage()
  currentPage.value =
    viewerRef.value?.getCurrentVisibleIndex() ?? currentPage.value
}

onMounted(() => {
  void initViewer()
})

/**
 * @description 组件卸载时释放 PDF 资源
 * @param 无
 * @returns void
 */
onBeforeUnmount(async () => {
  if (viewerRef.value) await viewerRef.value.destroy()
})
</script>

<style scoped>
.home {
  display: flex;
  flex-direction: column;
  height: 100vh;
}
.toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-bottom: 1px solid #e5e7eb;
}
.btn {
  padding: 6px 10px;
  border: 1px solid #cbd5e1;
  background: #fff;
  border-radius: 4px;
  cursor: pointer;
}
.scale {
  min-width: 64px;
  text-align: center;
}
.page {
  min-width: 80px;
  text-align: center;
}
.url {
  flex: 1;
  min-width: 240px;
  padding: 6px 8px;
  border: 1px solid #cbd5e1;
  border-radius: 4px;
}
.pdf-container {
  flex: 1;
  overflow: auto;
  background: #f3f4f6;
}
</style>
